package com.etoak.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.util.IdUtil;
import com.etoak.common.core.constant.CommonConstant;
import com.etoak.common.core.vo.ResultVO;
import com.etoak.common.redis.service.RedisService;
import com.etoak.vo.CodeVO;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 生成验证码 code url uuid
 */
@RestController 
@RequestMapping("/code")
public class CodeController {

    /**
     * Redis服务，用于存储验证码
     * 来自cloud-common.common-redis模块
     */
    @Autowired
    RedisService redisService;

    /**
     * 验证码生成器
     * DefaultKaptcha来自pom.xml中导入的kaptcha包
     */
    @Autowired
    DefaultKaptcha defaultKaptcha;

    @GetMapping("/getCode")
    public ResultVO getCode() throws IOException {
        // 验证码字符串 1+1=？@2
        //生成验证码文本
        String text = defaultKaptcha.createText();
        String[] textArray = text.split("@");

        /**
         * 将验证码的表达式结果写入 redis,设置五分钟有效期
         */
        //获取唯一Id,来自糊涂包
        String uuid = IdUtil.simpleUUID();
        //构建reids的key,其中CommonConstant.CODE_REDIS_KEY_PREFIX是redis的前缀,来自cloud-common.common-core
        String key = CommonConstant.CODE_REDIS_KEY_PREFIX + uuid;
        /**
         * 将验证码表达式写入Redis中，设置5分钟有效期
         * 其中textArray数组中第一位是验证码内容如1+1，第二位是验证码结果如2
         */
        redisService.setex(key,textArray[1],5, TimeUnit.MINUTES);


        //根据文本生成图片
        BufferedImage bufferedImage = defaultKaptcha.createImage(textArray[0]);
        /**
         * FastByteArrayOutputStream是糊涂包中提供的字节组输出流，
         * 用于将图片数据写入内存中的字节数组，比Java原生的性能更好
         * Java原生的(jdk)是ByteArrayOutputStraem
         */
        FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream();
        //将图片以png格式写入字节数组输出流
        /**
         * 第一个参数是图片对象，第二个参数是指定为jpg格式，第三个参数是目标输出流
         */
        ImageIO.write(bufferedImage, "jpg", outputStream);
        //将图片转为base64编码,等号右边整个都来自糊涂包
        String base64 = Base64.encode(outputStream.toByteArray());
        String codeUrl = "data:image/png;base64," + base64;
        CodeVO codeVO = new CodeVO(uuid,codeUrl);
        return ResultVO.success(codeVO);
    }
}

// => redisService 来自cloud-common.common-redis模块
